home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d20 / pvert.arc / QWK.C < prev    next >
Text File  |  1992-01-15  |  10KB  |  419 lines

  1. /*
  2.  *
  3.  * Basic QWK functions in C
  4.  * note these routines make some QWK<->Fidonet alterations
  5.  * so the two will cooperate better (snort -- yeah, right)...
  6.  * if you have to fool with the index file, #define USEFLOATS
  7.  *
  8.  */
  9.  
  10. #include <ctype.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <time.h>
  15. #include "qwk.h"
  16.  
  17. extern char * rstrip  (char *);
  18. extern char * lstrip  (char *);
  19. extern char * stripcr (char *);
  20.  
  21.  
  22.  
  23. QWKAREAS * qwkarearead (FILE *fp,long *numareas) {
  24.  
  25.     /* note that the file should have been read by the caller to
  26.      * line #11 (the "max number of conferences - 1" line), and
  27.      * that the file should be opened in text mode (all others
  28.      * should be opened in binary).  returns linked list of areas
  29.      */
  30.  
  31.     QWKAREAS *head = NULL,*last = NULL,*info;
  32.     char     s[81],tname[11],tnum[7],*p;
  33.     long     c = 0;
  34.  
  35.  
  36.     *numareas = 0L;
  37.     if(!fgets(s,80,fp)) return NULL;
  38.     *numareas = atol(s) + 1;
  39.  
  40.     while(!feof(fp) && c < *numareas) {
  41.         if(!fgets(s,80,fp)) {
  42.             *numareas = c;
  43.             break;
  44.         }
  45.         sprintf(tnum,"%d",atoi(s) + 1);
  46.         if(!fgets(s,80,fp)) {
  47.             *numareas = c;
  48.             break;
  49.         }
  50.         stripcr(s);
  51.         rstrip(s);
  52.         strncpy(tname,s,10);
  53.         tname[10] = 0;
  54.         p = tname;
  55.         while(*p) {
  56.             if(*p == ' ') *p = '_';
  57.             *p = (char)toupper(*p);
  58.             p++;
  59.         }
  60.         if(*tname) {                         /* build linked list */
  61.             info = malloc(sizeof(QWKAREAS));
  62.             if(!info) {
  63.                 *numareas = c;
  64.                 break;
  65.             }
  66.             info->confnum = atoi(tnum);     /* no longer zero based */
  67.             info->name = malloc(strlen(tname) + strlen(tnum) + 2);
  68.             if(!info->name) {
  69.                 *numareas = c;
  70.                 break;
  71.             }
  72.             sprintf(info->name,"%s_%s",tnum,tname); /* big-time barf */
  73.  
  74.             if(!head) head = info;
  75.             if(last) last->next = info;
  76.             info->next = NULL;
  77.             info->prev = last;
  78.             last = info;
  79.  
  80.             c++;
  81.         }
  82.         else *numareas--;
  83.     }
  84.  
  85.     return head;
  86. }
  87.  
  88.  
  89. void qwkfreeareas (QWKAREAS *head) {
  90.  
  91.     QWKAREAS *info = head,*next;
  92.  
  93.  
  94.     while(info) {
  95.         next = info->next;
  96.         if(info->name) free(info->name);
  97.         free(info);
  98.         info = next;
  99.     }
  100. }
  101.  
  102.  
  103.  
  104. #ifdef QWKIMPORT
  105.  
  106. size_t qwkreadhdr (FILE *fp,QWKHDR *hdr,int rep) {
  107.  
  108.     /* read and decode awful QWK message header
  109.      * if rep != 0 a reply packet is being read
  110.      */
  111.  
  112.     QWKHDRREADER h;
  113.     struct tm    tm;
  114.     char         date[14],p;
  115.  
  116.  
  117.     if(fread(&h,1,QWKBLKSIZE,fp) != QWKBLKSIZE) return 0;
  118.     hdr->status  = h.status;
  119.     hdr->confnum = h.confnum + 1;           /* no longer zero-based */
  120.     hdr->live = (char)QWK_ISALIVE(h.live);
  121.     h.live = 0;
  122.     hdr->numchunks = atol(h.numchunks) - 1L; /* exclude header */
  123.     *h.numchunks = 0;
  124.     hdr->repnum = atol(h.repnum);
  125.     *h.repnum = 0;
  126.     strcpy(hdr->pword,h.pword);
  127.     rstrip(hdr->pword);
  128.     *h.pword = 0;
  129.     strcpy(hdr->subj,h.subj);
  130.     rstrip(hdr->subj);
  131.     *h.subj = 0;
  132.     strcpy(hdr->from,h.from);
  133.     rstrip(hdr->from);
  134.     *h.from = 0;
  135.     strcpy(hdr->to,h.to);
  136.     rstrip(hdr->to);
  137.     *h.to = 0;
  138.     strcpy(date,h.date);
  139.     *h.date = 0;
  140.     if(!rep) hdr->msgnum = atol(h.msgnum);
  141.     else {
  142.         hdr->msgnum = 0;
  143.         hdr->confnum = atoi(h.msgnum) + 1;
  144.     }
  145.     date[2] = 0;
  146.     tm.tm_mon = atoi(date);
  147.     date[5] = 0;
  148.     tm.tm_mday = atoi(&date[3]);
  149.     p = date[8];
  150.     date[8] = 0;
  151.     tm.tm_year = atoi(&date[6]);
  152.     if(tm.tm_year < 89) tm.tm_year += 100;
  153.     date[8] = p;
  154.     date[10] = 0;
  155.     tm.tm_hour = atoi(&date[8]);
  156.     tm.tm_min = atoi(&date[11]);
  157.     tm.tm_sec = 0;
  158.     hdr->date = mktime(&tm);
  159.     return 1;
  160. }
  161.  
  162.  
  163.  
  164. size_t qwkreadblk (FILE *fp,char *blk) {
  165.  
  166.     /* read text block and convert 0xe3's to cr's
  167.      * note that blk must be at least QWKBLKSIZE + 1 in
  168.      * length to allow for NULL terminator.
  169.      */
  170.  
  171.     char *p = blk;
  172.  
  173.  
  174.     if(fread(blk,1,QWKBLKSIZE,fp) != QWKBLKSIZE) return 0;
  175.     blk[QWKBLKSIZE] = 0;
  176.     while((p = strchr(p,'\xe3')) != NULL) *p = '\r';
  177.     return 1;
  178. }
  179.  
  180.  
  181.  
  182. size_t qwkreadblks (FILE *fp,char *blk,size_t c) {
  183.  
  184.     /* read several text blocks and convert 0xe3's to cr's
  185.      * note that blk must be at least (QWKBLKSIZE * c) + 1
  186.      * in length to allow for NULL terminator
  187.      */
  188.  
  189.     char   *p = blk;
  190.  
  191.  
  192.     c = fread(blk,QWKBLKSIZE,c,fp);
  193.     if(!c) return 0;
  194.     blk[QWKBLKSIZE * c] = 0;
  195.     while((p = strchr(p,'\xe3')) != NULL) *p = '\r';
  196.     return c;
  197. }
  198.  
  199.  
  200.  
  201. #ifdef USEFLOATS
  202.  
  203. size_t qwkreadidx (FILE *fp,QWKIDX *i) {
  204.  
  205.     /* read QWK index record, convert nasty MSBIN to IEEE */
  206.  
  207.     if(fread(i,1,sizeof(QWKIDX),fp) != sizeof(QWKIDX)) return 0;
  208.     i->recnum = MSBINToIEEE(i->recnum);
  209.     return 1;
  210. }
  211.  
  212.  
  213.  
  214.  
  215. size_t qwkreadidxs (FILE *fp,QWKIDX **i,size_t c) {
  216.  
  217.     /* read several QWK index records, convert MSBIN to IEEE */
  218.  
  219.     size_t oc;
  220.  
  221.  
  222.     c = fread(i[0],sizeof(QWKIDX),c,fp);
  223.     if(!c) return 0;
  224.     oc = c;
  225.     while(c) {
  226.         i[c - 1]->recnum = MSBINToIEEE(i[c - 1]->recnum);
  227.         c--;
  228.     }
  229.     return oc;
  230. }
  231.  
  232. #endif
  233.  
  234. #endif
  235.  
  236.  
  237.  
  238. #ifdef QWKEXPORT
  239.  
  240. size_t qwkwritehdr (FILE *fp,QWKHDR *hdr,int rep) {
  241.  
  242.     /* encode and write awful QWK message header
  243.      * if rep != 0 then header is for reply packet
  244.      */
  245.  
  246.     QWKHDRREADER h;
  247.  
  248.  
  249.     h.status  = hdr->status;
  250.     if(!rep) sprintf(h.msgnum,"%-7ld",hdr->msgnum);
  251.     else sprintf(h.msgnum,"%-7d",hdr->confnum - 1); /* zero based again */
  252.     strftime(h.date,13,"%m/%d/%y%h:%m",localtime(&hdr->date));
  253.     sprintf(h.to,"%-25.25s",hdr->to);
  254.     sprintf(h.from,"%-25.25s",hdr->from);
  255.     sprintf(h.subj,"%-25.25s",hdr->subj);
  256.     sprintf(h.pword,"%-12.12s",hdr->pword);
  257.     sprintf(h.repnum,"%-8ld",hdr->repnum);
  258.     sprintf(h.numchunks,"%-6ld",hdr->numchunks + 1); /* add one for header */
  259.     if(hdr->live) h.live = 0xe1;
  260.     else h.live = 0xe2;
  261.     h.confnum = hdr->confnum - 1;   /* zero based again */
  262.     if(fwrite(&h,1,QWKBLKSIZE,fp) != QWKBLKSIZE) return 0;
  263.     return 1;
  264. }
  265.  
  266.  
  267.  
  268. size_t qwkwriteblk (FILE *fp,char *blk) {
  269.  
  270.     /* write text block after converting cr's to 0xe3's
  271.      * well, what it actually does is write a C string
  272.      * then pad with spaces if required...
  273.      * returns number of blocks written
  274.      */
  275.  
  276.     char   *p = blk;
  277.     size_t w,len;
  278.  
  279.  
  280.     while((p = strchr(p,'\r')) != NULL) *p = '\xe3';
  281.     len = strlen(blk);
  282.     len = min(len,QWKBLKSIZE);
  283.     w = fwrite(blk,1,len,fp);
  284.     if(!w || w == 65535U) return 0;   /* write error */
  285.     while(w++ < QWKBLKSIZE) {
  286.         fputc(' ',fp);
  287.     }
  288.     return 1;
  289. }
  290.  
  291.  
  292.  
  293. size_t qwkwriteblks (FILE *fp,char *blk) {
  294.  
  295.     /* write several text blocks after converting cr's to 0xe3's
  296.      * well, what it actually does is write a C string then
  297.      * pad to the nearest block with spaces if required...
  298.      * returns number of blocks written
  299.      */
  300.  
  301.     char   *p = blk;
  302.     size_t w,len;
  303.  
  304.  
  305.     while((p = strchr(p,'\r')) != NULL) *p = '\xe3';
  306.     len = strlen(blk);
  307.     w = fwrite(blk,1,len,fp);
  308.     if(!w || w == 65535U) return 0;  /* write error */
  309.     len = (w / QWKBLKSIZE) + ((w % QWKBLKSIZE) != 0);
  310.     w = (len * QWKBLKSIZE) - w;
  311.     while(w--) {
  312.         fputc(' ',fp);
  313.     }
  314.     return len;
  315. }
  316.  
  317.  
  318.  
  319. #ifdef USEFLOATS
  320.  
  321. size_t qwkwriteidx (FILE *fp,QWKIDX *i) {
  322.  
  323.     /* write QWK index record, convert IEEE to nasty MSBIN */
  324.  
  325.     i->recnum = IEEEToMSBIN(i->recnum);
  326.     if(fwrite(i,1,sizeof(QWKIDX),fp) != sizeof(QWKIDX)) return 0;
  327.     return 1;
  328. }
  329.  
  330.  
  331.  
  332.  
  333. size_t qwkwriteidxs (FILE *fp,QWKIDX **i,size_t c) {
  334.  
  335.     /* write several QWK index records, convert IEEE to MSBIN */
  336.  
  337.     size_t oc;
  338.  
  339.  
  340.     oc = c;
  341.     while(c) {
  342.         i[c - 1]->recnum = IEEEToMSBIN(i[c - 1]->recnum);
  343.         c--;
  344.     }
  345.     return fwrite(i[0],sizeof(QWKIDX),oc,fp);
  346. }
  347.  
  348. #endif
  349.  
  350. #endif
  351.  
  352.  
  353.  
  354. #ifdef USEFLOATS
  355.  
  356.  /***  MSBIN conversion routines from QWK.DOC by Jeffrey Foy ***/
  357.  
  358. union Converter {
  359.     unsigned char uc[10];
  360.     unsigned int  ui[5];
  361.     unsigned long ul[2];
  362.     float          f[2];
  363.     double         d[1];
  364. }
  365.  
  366.  /* MSBINToIEEE - Converts an MSBIN floating point number */
  367.  /*               to IEEE floating point format           */
  368.  /*                                                       */
  369.  /*  Input: f - floating point number in MSBIN format     */
  370.  /* Output: Same number in IEEE format                    */
  371.  
  372. float MSBINToIEEE (float f) {
  373.  
  374.     union Converter t;
  375.     int             sign, exp;       /* sign and exponent */
  376.  
  377.  
  378.     t.f[0] = f;
  379.  
  380.  /* extract the sign & move exponent bias from 0x81 to 0x7f */
  381.  
  382.     sign = t.uc[2] / 0x80;
  383.     exp  = (t.uc[3] - 0x81 + 0x7f) & 0xff;
  384.  
  385.  /* reassemble them in IEEE 4 byte real number format */
  386.  
  387.     t.ui[1] = (t.ui[1] & 0x7f) | (exp << 7) | (sign << 15);
  388.     return t.f[0];
  389. } /* End of MSBINToIEEE */
  390.  
  391.  
  392.  
  393.  /* IEEEToMSBIN - Converts an IEEE floating point number  */
  394.  /*               to MSBIN floating point format          */
  395.  /*                                                       */
  396.  /*  Input: f - floating point number in IEEE format      */
  397.  /* Output: Same number in MSBIN format                   */
  398.  
  399. float IEEEToMSBIN (float f) {
  400.  
  401.     union Converter t;
  402.     int             sign, exp;       /* sign and exponent */
  403.  
  404.  
  405.     t.f[0] = f;
  406.  
  407.  /* extract sign & change exponent bias from 0x7f to 0x81 */
  408.  
  409.     sign = t.uc[3] / 0x80;
  410.     exp  = ((t.ui[1] >> 7) - 0x7f + 0x81) & 0xff;
  411.  
  412.  /* reassemble them in MSBIN format */
  413.  
  414.     t.ui[1] = (t.ui[1] & 0x7f) | (sign << 7) | (exp << 8);
  415.     return t.f[0];
  416. } /* End of IEEEToMSBIN */
  417.  
  418. #endif
  419.